#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import json
import requests

from tpops.gaussdb.common.const import RpcParamKey, RequestInfo, TPOPS_TIMEOUT_FIVE_SECONDS
from tpops.gaussdb.common.log import log


def send_request(request_info: RequestInfo):
    url = request_info.request_url
    prefix = url.split("//")[0]
    ips = url.split("//")[1].split(":")[0].split(",")
    suffix = url.split("//")[1].split(":")[1]
    result = {}
    ret_body = {}
    exception = {}
    is_success = True
    for ip in ips:
        url = f"{prefix}//{ip}:{suffix}"
        log.info(f'Start to request url: {url}')
        try:
            request_info.request_url = url
            result, ret_body = exec_request(request_info)
            is_success = True
            break
        except Exception as err:
            exception = err
            is_success = False
            log.error(f'Exec {request_info.request_url} error with return: {err}')
    if not is_success:
        raise exception
    ret_headers = dict(result.headers)
    return True, ret_body, ret_headers


def exec_request(request_info: RequestInfo):
    method = request_info.request_method
    url = request_info.request_url
    body = request_info.request_body
    headers = request_info.request_header
    timeout = request_info.request_timeout
    if method == 'get':
        result = requests.get(url, json=body, headers=headers, verify=False, timeout=timeout)
    elif method == 'post':
        result = requests.post(url, json=body, headers=headers, verify=False, timeout=timeout)
    elif method == 'put':
        result = requests.put(url, json=body, headers=headers, verify=False, timeout=timeout)
    else:
        raise Exception(f'Method {method} is not supported.')
    ret_body = json.loads(result.content.decode())
    if "message" in ret_body and ret_body.get("message") != RpcParamKey.REST_SUCCESS:
        log.error(f'Exec {method} error with return: {ret_body.get("message")}')
        raise Exception(f'Request failed. error message: {ret_body.get("message")}')
    return result, ret_body


def get_request_post_http_code(url, body, headers):
    prefix = url.split("//")[0]
    ips = url.split("//")[1].split(":")[0].split(",")
    suffix = url.split("//")[1].split(":")[1]
    result = {}
    ret_body = {}
    exception = {}
    is_success = True
    for ip in ips:
        url = f"{prefix}//{ip}:{suffix}"
        try:
            result = requests.post(url, json=body, headers=headers, verify=False, timeout=TPOPS_TIMEOUT_FIVE_SECONDS)
            ret_body = json.loads(result.content.decode())
            is_success = True
            break
        except json.JSONDecodeError as err:
            log.warning(f'decode ret_body fail: {err}')
            is_success = True
        except Exception as err:
            exception = err
            log.error(f'Exec POST error with return: {err}')
            is_success = False
    if not is_success:
        raise exception
    return result.status_code, ret_body
